
package com.joysuch.wwyt.datadump.biz.query;

import cn.zlg.common.datadump.condition.*;
import cn.zlg.common.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.joysuch.wwyt.bp.repository.BpContractorStaffDao;
import com.joysuch.wwyt.bp.service.impl.BpContractorStaffServiceImpl;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.support.AuthorityScopeComponent;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.edu.entity.WwytEduCertificate;
import com.joysuch.wwyt.edu.entity.dsl.QEduCertificate;
import com.joysuch.wwyt.edu.entity.dsl.QEduCertificateUser;
import com.joysuch.wwyt.edu.mapper.WwytEduCertificateMapper;
import com.joysuch.wwyt.util.ApplicationContextHolder;
import com.joysuch.wwyt.util.StringUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;

import java.util.*;
import java.util.stream.Collectors;

public class EduCertificateDumpQueryBean implements QueryCondtionDef {

    @Override
    public boolean supportCustomBuild() {
        return true;
    }

    @Override
    public Predicate build(List<QueryFieldWithValue> list) {
        //人员条件
        String nameOrCode = (String) findFieldValue(list, "nameOrCode");
        Integer userContractorFlag = (Integer) findFieldValue(list, "userContractorFlag");

        List<Long> userIds = new ArrayList<>();
        if (StringUtil.notEmpty(nameOrCode)) {
            //删除的人员 持证也能查到
            if (userContractorFlag != null && userContractorFlag == 1) {
                userIds = ApplicationContextHolder.getBean(BpContractorStaffDao.class).findIdsByNameOrCode(nameOrCode);
            } else if (userContractorFlag != null && userContractorFlag == 0) {
                userIds = ApplicationContextHolder.getBean(BaseUserDao.class).findIdsByRealNameContainingOrCodeContaining(nameOrCode);
            }
            if (CollectionUtils.isEmpty(userIds)) {
                return null;
            }
        }

        //证书类型条件
        Long certTypeId = (Long) findFieldValue(list, "certTypeId");
        List<Long> certIds = new ArrayList<>();
        Long certId = (Long) findFieldValue(list, "certId");;
        if (certTypeId != null && certId != null) {
            //证书id查询出该证书的certTypeId,要是不同直接让查不到
            WwytEduCertificate certificate = ApplicationContextHolder.getBean(WwytEduCertificateMapper.class).selectById(certId);
            Long dbCertTypeId = certificate.getCertTypeId();
            if (certTypeId.equals(dbCertTypeId)) {
                certIds.add(certId);
            } else {
                certIds.add(-2L);
            }
        } else if (certTypeId != null && certId == null) {
            LambdaQueryWrapper<WwytEduCertificate> eq = new QueryWrapper<WwytEduCertificate>().lambda()
                    .eq(WwytEduCertificate::getCertTypeId, certTypeId);
            List<WwytEduCertificate> wwytEduCertificates = ApplicationContextHolder.getBean(WwytEduCertificateMapper.class).selectList(eq);
            //证书表中使用这个证书种类的证书ids
            List<Long> typeUsedIds = wwytEduCertificates.stream().map(WwytEduCertificate::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(typeUsedIds)) {
                certIds.addAll(typeUsedIds);
            } else {
                //传了certTypeId  但是没找到  就让他查不到
                certIds.add(-2L);
            }
        } else if (certTypeId == null && certId != null) {
            certIds.add(certId);
        }
        ArrayList<Long> objects = new ArrayList<>();
        objects.add(-2L);
        //查看当前账号是否是管理员
        boolean isSuperAdmin = Context.getCurrentUser().isSuperAdmin();

        Predicate p = null;
        QEduCertificateUser q = QEduCertificateUser.eduCertificateUser;
        if(userContractorFlag != null) {
            p = ExpressionUtils.and(p, q.userContractorFlag.eq(userContractorFlag));
        }
        Set<Long> authorityUserIds = null;
        if(!isSuperAdmin ) {
            //1代表是承包商人员，0是人员
            if (Integer.valueOf(1).equals(userContractorFlag)){
                authorityUserIds = ApplicationContextHolder.getBean(BpContractorStaffServiceImpl.class).findStaffIds();
            }else {
                authorityUserIds = ApplicationContextHolder.getBean(AuthorityScopeComponent.class).authorityUserIdData();
            }
            if(!CollectionUtils.isEmpty(authorityUserIds)) {
                //不是超级管理员并且有权限
                p = ExpressionUtils.and(p, q.userId.in(authorityUserIds));
            } else {
                //不是超级管理员并且没有权限 使其查不到
                p = ExpressionUtils.and(p, q.userId.in(objects));
            }
        }

        if(!CollectionUtils.isEmpty(userIds)) {
            p = ExpressionUtils.and(p, q.userId.in(userIds));
        }
        if(!CollectionUtils.isEmpty(certIds)) {
            p = ExpressionUtils.and(p, q.certId.in(certIds));
        }

        Date effectQueryStartTime = (Date) findFieldValue(list, "effectQueryStartTime");
        Date effectQueryEndTime = (Date) findFieldValue(list, "effectQueryEndTime");
        if(effectQueryStartTime != null && effectQueryEndTime != null) {
            p = ExpressionUtils.and(p, q.outOfDateTime.between(effectQueryStartTime, effectQueryEndTime));
        }

        Date reviewQueryStartTime = (Date) findFieldValue(list, "reviewQueryStartTime");
        Date reviewQueryEndTime = (Date) findFieldValue(list, "reviewQueryEndTime");
        if(reviewQueryStartTime != null && reviewQueryEndTime != null) {
            p = ExpressionUtils.and(p, q.repeatViewDateDime.between(reviewQueryStartTime, reviewQueryEndTime));
        }

        Integer certificateStatus = (Integer) findFieldValue(list, "certificateStatus");
        if(certificateStatus != null) {
            p = ExpressionUtils.and(p, q.certificateStatus.eq(certificateStatus));
        }

        List<Long> ids = (List<Long>) findFieldValue(list, "ids");
        if(ids != null && ids.size() > 0) {
            p = ExpressionUtils.and(p, q.id.in(ids));
        }
//        System.err.println("build conditions=" + p);
        return p;
    }

    @Override
    public QueryFieldCondition[] getAllConditionDef() {
        QEduCertificateUser q = QEduCertificateUser.eduCertificateUser;
        QEduCertificate c = QEduCertificate.eduCertificate;
        return new QueryFieldCondition[] {
                new QueryFieldCondition("ids", q,  q.id, q.id, "in"),

                // nameOrCode对应的应该是人名，没有关联到那具体实体，只是找到一个相同属性的类型，接收值，在自定义构建方法中查询
                 new QueryFieldCondition("nameOrCode", q, q.certNo, q.id, "contains"),

                 new QueryFieldCondition("effectQueryStartTime", q, q.outOfDateTime, q.id, "after"),
                 new QueryFieldCondition("effectQueryEndTime", q, q.outOfDateTime, q.id, "before"),

                 new QueryFieldCondition("reviewQueryStartTime", q, q.repeatViewDateDime, q.id, "before"),
                 new QueryFieldCondition("reviewQueryEndTime", q, q.repeatViewDateDime, q.id, "after"),

                new QueryFieldCondition("certTypeId", c,  c.certTypeId, c.id,  q.certId, "eq"),
                new QueryFieldCondition("certId", q, q.certId, q.id, "eq"),

                new QueryFieldCondition("certificateStatus", q, q.certificateStatus, q.id, "eq"),
                // 人员类型
                new QueryFieldCondition("userContractorFlag", q, q.userContractorFlag, q.id, "eq"),
        };
    }

    @Override
    public SortFieldDef[] getAllSortFieldDef() {
        return new SortFieldDef[] {};
    }
}
